package dateFitting;

import java.util.ArrayList;
import java.util.List;

public class DataHandle {
    public static void main(String[] args) {
        DataRead.initialize(".\\src\\main\\resources\\resource\\工时B4新.xlsx",30,9,0);
        List<DataRead.PartData> trainData= DataRead.getTrainingSet();
//        for (DataRead.PartData trainDatum : trainData) {
//            System.out.println(trainDatum);
//        }
        List<DataRead.PartData> testData= DataRead.getTestSet();
        List<DataRead.PartData> totalData=new ArrayList<>(trainData);
        totalData.addAll(testData);
        // 计算误差
        double trainError =Comparsion.evaluateDataSet(trainData);
        double testError = Comparsion.evaluateDataSet(testData);
        double totalError=Comparsion.evaluateDataSet(totalData);

        System.out.println("\n固定比例模型评估结果:");
        System.out.println("训练集误差: " + trainError);
        System.out.println("测试集误差: " + testError);
        System.out.println("全部集合误差: " + totalError);

        // 打印几个样本的预测结果
        if (!testData.isEmpty()) {
            for (int i = 0; i < Math.min(10, testData.size()); i++) {
                System.out.println("\n测试集第" + i + "个样本的预测:");
                Comparsion.printPredictions(testData.get(i));
            }
        }
        System.out.println("开始训练公式1");
        function1.LearningParameters bestParams1 = function1.estimateParametersMultipleStarts(trainData, testData);
        double trainError1 = function1.evaluateDataSet(trainData, bestParams1);
        double testError1 = function1.evaluateDataSet(testData, bestParams1);
        double totalError1 = function1.evaluateDataSet(totalData, bestParams1);
        System.out.println("最优参数: " + bestParams1);
        System.out.println("训练集误差: " + trainError1);
        System.out.println("测试集误差: " + testError1);
        System.out.println("全部集合误差: " + totalError1);
        if (!testData.isEmpty()) {
            for (int i = 0; i <testData.size(); i++) {
                System.out.println("\n测试集第"+i+"个样本的预测:");
                function1.printPredictions(testData.get(i), bestParams1);
            }
        }
        System.out.println("开始训练公式2");
        function2.LearningParameters bestParams2 = function2.estimateParametersMultipleStarts(trainData, testData);
        double trainError2 = function2.evaluateDataSet(trainData, bestParams2);
        double testError2 = function2.evaluateDataSet(testData, bestParams2);
        double totalError2 = function2.evaluateDataSet(totalData, bestParams2);
        System.out.println("最优参数: " + bestParams2);
        System.out.println("训练集误差: " + trainError2);
        System.out.println("测试集误差: " + testError2);
        System.out.println("全部集合误差: " + totalError2);
        if (!testData.isEmpty()) {
            for (int i = 0; i < testData.size(); i++) {
                System.out.println("\n测试集第" + i + "个样本的预测:");
                function2.printPredictions(testData.get(i), bestParams2);
            }
        }
        System.out.println("开始训练公式3");
        function3.LearningParameters bestParams3 = function3.estimateParametersMultipleStarts(trainData, testData);
        double trainError3 = function3.evaluateDataSet(trainData, bestParams3);
        double testError3 = function3.evaluateDataSet(testData, bestParams3);
        double totalError3 = function3.evaluateDataSet(totalData, bestParams3);
        System.out.println("最优参数: " + bestParams3);
        System.out.println("训练集误差: " + trainError3);
        System.out.println("测试集误差: " + testError3);
        System.out.println("全部集合误差: " + totalError3);

        if (!testData.isEmpty()) {
            for (int i = 0; i < testData.size(); i++) {
                System.out.println("\n测试集第" + i + "个样本的预测:");
                function3.printPredictions(testData.get(i), bestParams3);
            }
        }
        // 添加学习曲线示例
        if (!testData.isEmpty()) {
            System.out.println("\n学习曲线示例:");
            DataRead.PartData sampleData = testData.get(0);
            double baseTime = sampleData.getTime1();

            // 打印不同重复次数的学习曲线
            System.out.println("重复次数与处理时间的关系:");
            System.out.println("重复次数\t单件时间\t总时间\t效率提升(%)");

            double initialTime = function3.predictTime(baseTime, bestParams3.alpha, bestParams3.m, 1);

            for (int r = 1; r <= 100; r += 10) {
                double currentTime = function3.predictTime(baseTime, bestParams3.alpha, bestParams3.m, r);
                double improvement = (initialTime - currentTime) / initialTime * 100;

                System.out.printf("%d\t%.2f\t%.2f\t%.2f%%\n",
                        r, currentTime, currentTime * r, improvement);
            }

            // 计算最小不可压缩时间
            double minTime = baseTime * bestParams3.m;
            double maxImprovement = (initialTime - minTime) / initialTime * 100;

            System.out.printf("\n理论最小时间: %.2f (原始时间的 %.1f%%)\n",
                    minTime, (minTime/baseTime)*100);
            System.out.printf("理论最大效率提升: %.2f%%\n", maxImprovement);
        }
        System.out.println("开始训练公式4");
        function4.LearningParameters bestParams4 = function4.estimateParametersMultipleStarts(trainData, testData);
        double trainError4 = function4.evaluateDataSet(trainData, bestParams4);
        double testError4 = function4.evaluateDataSet(testData, bestParams4);
        double totalError4 = function4.evaluateDataSet(totalData, bestParams4);
        System.out.println("最优参数: " + bestParams4);
        System.out.println("训练集误差: " + trainError4);
        System.out.println("测试集误差: " + testError4);
        System.out.println("全部集合误差: " + totalError4);

        if (!testData.isEmpty()) {
            for (int i = 0; i < testData.size(); i++) {
                System.out.println("\n测试集第" + i + "个样本的预测:");
                function4.printPredictions(testData.get(i), bestParams4);
            }
        }

        // 添加学习曲线分析
//        if (!testData.isEmpty()) {
//            System.out.println("\n学习曲线分析:");
//            DataRead.PartData sampleData = testData.get(0);
//            double baseTime = sampleData.getTime1();
//
//            // 打印不同重复次数的学习曲线
//            System.out.println("累积经验与处理时间的关系:");
//            System.out.println("累积时间\t单件时间\t效率提升(%)\t是否达到限制");
//
//            double initialTime = function4.predictTime(baseTime, bestParams4.alpha, bestParams4.theta,
//                    bestParams4.m, 0, 1);
//
//            // 模拟不同累积时间下的学习效果
//            double[] cumulativeTimes = {0, 10, 50, 100, 200, 500, 1000};
//
//            for (double cumTime : cumulativeTimes) {
//                double currentTime = function4.predictTime(baseTime, bestParams4.alpha, bestParams4.theta,
//                        bestParams4.m, cumTime, 1);
//                double improvement = (initialTime - currentTime) / initialTime * 100;
//
//                // 判断是否达到不可压缩限制
//                double learningTerm = Math.pow(1 + bestParams4.theta * cumTime, bestParams4.alpha);
//                String limitReached = (bestParams4.m > learningTerm) ? "是" : "否";
//
//                System.out.printf("%.0f\t%.2f\t%.2f%%\t%s\n",
//                        cumTime, currentTime, improvement, limitReached);
//            }
//        }
    }
}
